home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-11-22 | 55.0 KB | 1,434 lines |
- *-----------------------------------------------------------------------
- *-- Program...: CONVERT.PRG
- *-- Programmer: Ken Mayer (CIS: 71333,1030)
- *-- Date......: 08/27/1993
- *-- Notes.....: This is a complete overhaul of the CONVERT program in
- *-- LIBxxx.ZIP - Jay went through it and did massive work.
- *-- For details on this file (and others in the library) see
- *-- README.TXT.
- *-----------------------------------------------------------------------
-
- FUNCTION Roman
- *-----------------------------------------------------------------------
- *-- Programmer..: Nick Carlin
- *-- Date........: 08/27/1993
- *-- Notes.......: A function designed to return a Roman Numeral based on
- *-- an Arabic Numeral input ...
- *-- Written for.: dBASE III+
- *-- Rev. History: 04/13/1988 - original function.
- *-- 07/25/1991 - Ken Mayer - 1) modified for dBASE IV,
- *-- 1.1, 2) updated to a function, and
- *-- 3) the procedure GetRoman was done away
- *-- with (combined into the function).
- *-- 04/26/1992 - Jay Parsons - shortened (seriously ...)
- *-- 08/27/1993 - Jay Parsons - dBASE IV 2.0 bug worked
- *-- around
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Roman(<nArabic>)
- *-- Example.....: ? Roman(32)
- *-- Returns.....: Roman Numeral (character string) equivalent of Arabic
- *-- numeral passed to it. In example: XXXII
- *-- Parameters..: nArabic = Arabic number to be converted to Roman
- *-----------------------------------------------------------------------
-
- parameters nArabic
- private cLetrs,cRoman,nCount,nLeft,nMod,nNines,cAdd
-
- m->cLetrs ="IVXLCDMWY" && Roman digits
- m->cRoman = "" && this will be the returned value
- m->nCount = 0 && init counter
- m->nLeft = fixed( m->nArabic )
- if m->nLeft < 0 .or. m->nLeft # int( m->nLeft )
- RETURN m->cRoman
- endif
- do while m->nCount < 4 .and. m->nLeft > 0 && loop four times, once
- && each for 1s, 10s,
- && 100s, 1000s
- m->nMod = mod( m->nLeft, 10 )
- m->nLeft = int( m->nLeft / 10 )
- m->cGroup = substr( m->cLetrs, 2 * m->nCount + 1, 3 )
- m->cAdd = ""
- do case
- case m->nMod = 9
- m->cAdd = left( m->cGroup, 1 ) + right( m->cGroup, 1 )
- case m->nMod = 4
- m->cAdd = left( m->cGroup, 2 )
- otherwise
- if m->nMod > 4 && 5 - 8
- m->cAdd = substr( m->cGroup, 2, 1 )
- m->nMod = m->nMod - 5
- endif
- if m->nMod > 0 && 1 - 3 and 6 - 8
- m->cAdd = m->cAdd + replicate(left( m->cGroup, 1 ), m->nMod)
- endif
- endcase
- m->cRoman = m->cAdd + m->cRoman
- m->nCount = m->nCount + 1
- enddo && while nCounter < 4
-
- RETURN m->cRoman
- *-- EoF: Roman()
-
- FUNCTION Arabic
- *-----------------------------------------------------------------------
- *-- Programmer..: Ken Mayer (CIS: 71333,1030)
- *-- Date........: 04/26/1992
- *-- Notes.......: This function converts a Roman Numeral to an arabic
- *-- one. It parses the roman numeral into an array, and
- *-- checks each character ... if the previous character
- *-- causes the value to subtract (for example, IX = 9,
- *-- not 10) we subtract that value, and then set the
- *-- previous value to 0, otherwise we would get
- *-- some odd values in return. So far, it works fine.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 07/15/1991 - original function.
- *-- 04/26/1992 - Jay Parsons - shortened.
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Arabic(<cRoman>)
- *-- Example.....: ?Arabic("XXIV")
- *-- Returns.....: Arabic number (from example, 24)
- *-- Parameters..: cRoman = character string containing roman numeral to
- *-- be converted.
- *-----------------------------------------------------------------------
-
- parameters cRoman
- private cRom,cLetrs,nLast,nAt,nVal,cChar,nArabic
-
- m->cRom = ltrim(trim(upper(m->cRoman))) &&convert to all caps in case
- m->cLetrs = "IVXLCDMWY"
- m->nArabic = 0
- m->nLast = 0
- do while len( m->cRom ) > 0
- m->cChar = right( m->cRom, 1 )
- m->nAt = at( m->cChar, m->cLetrs )
- m->nVal= 10 ^ int( m->nAt/2 ) / iif(m->nAt/2 = int(m->nAt/2),2,1)
- do case
- case m->nAt = 0
- m->nArabic = 0
- exit
- case m->nAt >= m->nLast
- m->nArabic = m->nArabic + m->nVal
- m->nLast = m->nAt
- otherwise
- if m->nAt/2 = int( m->nAt / 2 )
- m->nArabic = 0
- exit
- else
- m->nArabic = m->nArabic - m->nVal
- endif
- endcase
- m->cRom = left( m->cRom, len( m->cRom ) - 1 )
- enddo
-
- RETURN m->nArabic
- *-- EoF: Arabic()
-
- FUNCTION Factorial
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Factorial of a number; returns -1 if number is not a
- *-- positive integer.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Factorial(<nNumber>)
- *-- Example.....: ? Factorial( 6 )
- *-- Returns.....: Numeric = number factorial <in example, 6! or 720>
- *-- Parameters..: nNumber = number for which factorial is to be
- *-- determined
- *-----------------------------------------------------------------------
-
- parameters nNumber
- private nNext, nProduct
-
- if m->nNumber # int( m->nNumber ) .or. m->nNumber < 1
- RETURN -1
- endif
- m->nProduct = 1
- m->nNext = m->nNumber
- do while m->nNext > 1
- m->nProduct = m->nProduct * m->nNext
- m->nNext = m->nNext - 1
- enddo
-
- RETURN m->nProduct
- *-- Eof: Factorial()
-
- FUNCTION IsPrime
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 08/11/1992
- *-- Notes.......: Returns .t. if argument is prime positive integer, or
- *-- .f.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/11/92 - original function.
- *-- : 08/11/92 - revised to return .T. for 2. (Tea for two?)
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: IsPrime(<nNumber>)
- *-- Example.....: ? IsPrime( 628321 )
- *-- Returns.....: Logical = .t. if prime
- *-- Parameters..: nNumber = positive integer to test for being prime
- *-----------------------------------------------------------------------
-
- parameters nNumber
- private nFactor, nLimit, lResult
-
- if m->nNumber < 1 .or. m->nNumber # int( m->nNumber ) ;
- .or. ( m->nNumber > 2 .AND. mod( m->nNumber, 2 ) = 0 )
- RETURN .f.
- endif
- m->nFactor = 3
- m->nLimit = sqrt( m->nNumber )
- m->lResult = .t.
- do while m->nFactor <= m->nLimit
- if mod( m->nNumber, m->nFactor ) = 0
- m->lResult = .f.
- exit
- endif
- m->nFactor = m->nFactor + 2
- enddo
-
- RETURN m->lResult
- *-- Eof: IsPrime()
-
- FUNCTION BankRound
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Rounds numeric argument to given number of places,
- *-- which if positive are decimal places, otherwise
- *-- trailing zeroes before the decimal, in accordance
- *-- with the special banker's rule that if the value
- *-- lost by rounding is exactly halfway between two
- *-- possible digits, the final digit expressed will be
- *-- even.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: BankRound(<nNumber>,<nPlaces>)
- *-- Example.....: ? BankRound( 357.725, 2 )
- *-- Returns.....: Numeric = rounded value ( 357.72 in example )
- *-- Parameters..: nNumber = numeric value to round
- *-- nPlaces = decimal places, negative being powers of 10
- *-----------------------------------------------------------------------
-
- parameters nNumber, nPlaces
- private nTemp
-
- m->nTemp = m->nNumber * 10 ^ m->nPlaces +.5
- if m->nTemp = int( m->nTemp ) .and. m->nTemp / 2 # int(m->nTemp / 2)
- m->nTemp = m->nTemp - 1
- endif
-
- RETURN int( m->nTemp ) / 10 ^ m->nPlaces
- *-- Eof: BankRound()
-
- FUNCTION Dec2Hex
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts an unsigned integer ( in decimal notation)
- *-- to a hexadecimal string
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Dec2Hex(<nDecimal>)
- *-- Example.....: ? Dec2Hex( 118 )
- *-- Returns.....: Character = Hexadecimal equivalent ( "F6" in example )
- *-- Parameters..: nDecimal = number to convert
- *-----------------------------------------------------------------------
-
- parameters nDecimal
- private nD, cH
-
- m->nD = int( m->nDecimal )
- m->cH= ""
- do while m->nD > 0
- m->cH = substr( "0123456789ABCDEF", mod( m->nD, 16 ) + 1 , 1 );
- + m->cH
- m->nD = int( m->nD / 16 )
- enddo
-
- RETURN iif( "" = m->cH, "0", m->cH )
- *-- Eof: Dec2Hex()
-
- FUNCTION Hex2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/26/1992
- *-- Notes.......: Converts a hexadecimal character string representing
- *-- an unsigned integer to its numeric (decimal)
- *-- equivalent.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/92 - original function.
- *-- 11/26/92 - modified to eliminate usually-harmless
- *-- "substring out of range" error, Jay Parsons
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Hex2Dec(<cHex>)
- *-- Example.....: ? Hex2Dec( "F6" )
- *-- Returns.....: Numeric = equivalent ( 118 in example )
- *-- Parameters..: cHex = character string to convert
- *-----------------------------------------------------------------------
-
- parameters cHex
- private nD, cH
-
- m->cH = upper( trim( ltrim ( m->cHex ) ) ) + "!"
- m->nD = 0
- do while len( cH ) > 1
- m->nD = m->nD * 16 + at( left( m->cH, 1 ), "123456789ABCDEF" )
- m->cH = substr( m->cH, 2 )
- enddo
-
- RETURN m->nD
- *-- Eof: Hex2Dec()
-
- FUNCTION Hex2Bin
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 12/01/1992
- *-- Notes.......: Converts a hexadecimal character string representing
- *-- an unsigned integer to its binary string equivalent
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/92 - original function.
- *-- 12/01/92 - modified to eliminate usually-harmless
- *-- "substring out of range" error, Jay Parsons
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Hex2Bin(<cHex>)
- *-- Example.....: ? Hex2Bin( "F6" )
- *-- Returns.....: Character = binary string ( "1111 0110" in example )
- *-- Parameters..: cHex = character string to convert
- *-----------------------------------------------------------------------
-
- parameters cHex
- private cH, cBits, cNybbles, cVal
-
- m->cH = upper( trim( ltrim( m->cHex ) ) ) + "!"
- m->cBits = ""
- m->cNybbles = "00000001001000110100010101100111" ;
- +"10001001101010111100110111101111"
- do while len( m->cH ) > 1
- m->cVal = left( m->cH, 1 )
- if m->cVal # " "
- m->cBits = m->cBits + " " + substr( m->cNybbles, ;
- at ( m->cVal, "123456789ABCDEF" ) * 4 + 1, 4 )
- endif
- m->cH = substr( m->cH, 2 )
- enddo
-
- RETURN iif( "" = m->cBits, "0", ltrim( m->cBits ) )
- *-- Eof: Hex2Bin()
-
- FUNCTION Bin2Hex
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts a binary character string representing
- *-- an unsigned integer to its hexadecimal string
- *-- equivalent.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Bin2Hex(<cBin>)
- *-- Example.....: ? Bin2Hex( "1111 0110" )
- *-- Returns.....: Character = hexadecimal string ( "F6" in example )
- *-- Parameters..: cBin = character string to convert
- *-----------------------------------------------------------------------
-
- parameters cBin
- private cH, cBits, nBits, nBval, cNext
-
- m->cBits = trim( ltrim( m->cBin ) )
- m->nBits = len( m->cBits ) - 1
- do while m->nBits > 0
- if substr( m->cBits, m->nBits, 1 ) $ ", "
- m->nBVal = mod( 4 - mod( len( m->cBits ) - m->nBits, 4 ), 4 )
- m->cBits = stuff( m->cBits, m->nBits, 1, ;
- replicate( "0", m->nBVal ) )
- endif
- m->nBits = m->nBits - 1
- enddo
- m->cH = ""
- do while "" # m->cBits
- store 0 to m->nBits, m->nBVal
- do while m->nBits < 4
- m->cNext = right( m->cBits, 1 )
- m->nBVal = m->nBVal + iif( m->cNext = "1", 2 ^ m->nBits, 0 )
- m->cBits = left( m->cBits, len( m->cBits ) - 1 )
- if "" = m->cBits
- exit
- endif
- m->nBits = m->nBits + 1
- enddo
- m->cH = substr( "0123456789ABCDEF", m->nBVal + 1, 1 ) + m->cH
- enddo
-
- RETURN iif( "" = m->cH, "0", m->cH )
- *-- Eof: Bin2Hex()
-
- FUNCTION Dec2Oct
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts an unsigned integer to its octal string
- *-- equivalent
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Dec2Oct(<nDec>)
- *-- Example.....: ? Dec2Oct( 118 )
- *-- Returns.....: Character = octal string ( "166" in example )
- *-- Parameters..: nDec = number to convert
- *-----------------------------------------------------------------------
-
- parameters nDec
- private nD, cO
-
- m->nD = int( m->nDec )
- m->cO = ""
- do while m->nD > 0
- m->cO = substr( "01234567", mod( m->nD, 8 ) + 1 , 1 ) + m->cO
- m->nD = int( m->nD / 8 )
- enddo
-
- RETURN iif( "" = m->cO, "0", m->cO )
- *-- Eof: Dec2Oct()
-
- FUNCTION Oct2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 12/01/1992
- *-- Notes.......: Converts an unsigned number in octal, or its string
- *-- representation, to a numeric (decimal) value
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/92 - original function.
- *-- 12/01/92 - modified to eliminate usually-harmless
- *-- "substring out of range" error, Jay Parsons
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Oct2Dect(<xOct>)
- *-- Example.....: ? Oct2Dec( 166 )
- *-- Returns.....: Numeric = decimal equivalent ( 118 in example )
- *-- Parameters..: xOct = octal character string or number to convert
- *-----------------------------------------------------------------------
-
- parameters xOct
- private nD, cO, cVal
-
- if type( "xOct" ) $ "NF"
- m->cO = str( m->xOct )
- else
- m->cO = m->xOct
- endif
- m->cO = upper( trim( ltrim( m->cO ) ) ) + "!"
- m->nD = 0
- do while len( m->cO ) > 1
- m->cVal = left( m->cO, 1 )
- if m->cVal # " "
- m->nD = m->nD * 8 + at( m->cVal, "1234567" )
- endif
- m->cO = substr( m->cO, 2 )
- enddo
-
- RETURN m->nD
- *-- Eof: Oct2Dec()
-
- FUNCTION Cash2Check
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts a number of dollars and cents to a string of
- *-- words appropriate for writing checks.
- *-- To correctly evaluate values over 16 decimal places,
- *-- SET PRECISION TO a value larger than the default of 16
- *-- before calling this function.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: NUM2WORDS() Function in CONVERT.PRG
- *-- THOU2WORDS() Function in CONVERT.PRG
- *-- Called by...: Any
- *-- Usage.......: Cash2Check(<nCash>)
- *-- Example.....: ? Cash2Check( 348.27 )
- *-- Returns.....: Character string equivalent
- *-- Parameters..: nCash = money value to convert
- *-----------------------------------------------------------------------
-
- parameters nCash
- private nDollars, nCents, cResult
-
- m->nDollars = int( m->nCash )
- m->nCents = 100 * round( m->nCash - m->nDollars, 2 )
- m->nResult = trim( Num2Words( m->nDollars ) )
- if left( m->nResult, 1 ) = "C" && deals with oversize number
- RETURN m->nResult
- endif
- m->nResult = m->nResult + " dollar" + ;
- iif( m->nDollars # 1, "s", "" ) + " and "
- if m->nCents # 0
- RETURN m->nResult + Thou2Words( m->nCents ) + " cent" + ;
- iif( m->nCents # 1, "s", "" )
- else
- RETURN m->nResult + "no cents"
- endif
-
- *-- Eof: Cash2Check()
-
- FUNCTION Num2Words
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts an integer to a string of words. Limited,
- *-- due to 254-character limit of dBASE strings, to
- *-- numbers less than 10 ^ 15
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: THOU2WORDS() Function in CONVERT.PRG
- *-- Called by...: Any
- *-- Usage.......: Num2Words(<nNum>)
- *-- Example.....: ? Num2Words( 4321568357 )
- *-- Returns.....: Character string equivalent
- *-- Parameters..: nNum = numeric integer to convert
- *-----------------------------------------------------------------------
-
- parameters nNum
- private nNumleft, nScale, nGroup, cResult
-
- m->nNumLeft = int( m->nNum )
- do case
- case abs( m->nNumLeft ) >= 10 ^ 15
- RETURN "Cannot convert a number in or above the quadrillions."
- case m->nNumLeft = 0
- RETURN "zero"
- case m->nNumLeft < 0
- m->nResult = "minus "
- m->nNumLeft = -m->nNumLeft
- otherwise
- m->nResult = ""
- endcase
- do while m->nNumLeft > 0
- m->nScale = int( log10( m->nNumLeft ) / 3 )
- m->nGroup = int( m->nNumLeft / 10 ^ ( 3 * m->nScale ) )
- m->nNumLeft = mod( m->nNumLeft, 10 ^ ( 3 * m->nScale ) )
- m->nResult = m->nResult + Thou2Words( m->nGroup )
- if m->nScale > 0
- m->nResult = m->nResult + " " ;
- + trim( substr( "thousandmillion billion trillion",;
- m->nScale * 8 - 7, 8 ) )
- if m->nNumLeft > 0
- m->nResult = m->nResult + ", "
- endif
- endif
- enddo
-
- RETURN m->nResult
- *-- Eof: Num2Words()
-
- FUNCTION Thou2Words
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts a positive integer less than 1000 to a string
- *-- of characters.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Thou2Words(<nNum>)
- *-- Example.....: ? Thou2Words( 834 )
- *-- Returns.....: Character string equivalent
- *-- Parameters..: nNum = numeric integer to convert
- *-----------------------------------------------------------------------
-
- parameters nNum
- private cUnits, cTens, nN, cResult
-
- m->cUnits = "one two " ;
- + "three four " ;
- + "five six " ;
- + "seven eight " ;
- + "nine ten " ;
- + "eleven twelve " ;
- + "thirteen fourteen " ;
- + "fifteen sixteen " ;
- + "seventeeneighteen " ;
- + "nineteen "
- m->cTens = "twen thir for fif six seveneigh nine "
- m->nN = int( m->nNum )
- if m->nN = 0
- RETURN "zero"
- endif
- m->nResult = ""
- if m->nNum > 99
- m->nResult = trim( substr(m->cUnits, int(m->nNum / 100 ) ;
- * 9 - 8, 9 ) ) + " hundred"
- m->nN = mod( m->nN, 100 )
- if m->nN = 0
- RETURN m->nResult
- else
- m->nResult = m->nResult + " "
- endif
- endif
- if m->nN > 19
- m->nResult = m->nResult + trim( substr( m->cTens, ;
- int( m->nN / 10 ) * 5 - 9, 5 ) ) + "ty"
- m->nN = mod( m->nN, 10 )
- if m->nN = 0
- RETURN m->nResult
- else
- m->nResult = m->nResult + "-"
- endif
- endif
-
- RETURN m->nResult + trim( substr( m->cUnits, m->nN * 9 - 8, 9 ) )
- *-- Eof: Thou2Words()
-
- FUNCTION Ord
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts an integer to ordinal representation by
- *-- adding "st", "nd", "rd" or "th" after its digit(s)
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Ord(<nNum>)
- *-- Example.....: ? Ord( 11 )
- *-- Returns.....: Character ordinal string equivalent ( "11th" in
- *-- example )
- *-- Parameters..: nNum = numeric integer to convert
- *-----------------------------------------------------------------------
-
- parameters nNum
- private nD
-
- m->nD = mod( m->nNum, 100 ) - 1
- && the -1 just happens to simplify what follows
-
- RETURN str( m->nNum ) + iif( mod( m->nD, 10 ) > 2 .or. ;
- abs( m->nD - 11 ) < 2, "th", substr( "stndrd", mod( m->nD, 10 );
- * 2 + 1, 2 ) )
- *-- Eof: Ord()
-
- FUNCTION Dec2Bin
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts an unsigned number to a character
- *-- string giving its ASCII binary representation.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Dec2Bin(<nNum>,<nPlaces>)
- *-- Example.....: ? Dec2Bin( 35, 8 )
- *-- Returns.....: Character binary equivalent ( "0010 0011", in example)
- *-- Parameters..: nNum = number to convert
- *-- nPlaces = number of binary places number is to occupy
- *-----------------------------------------------------------------------
-
- parameters nNum, nPlaces
- private cBits, nN
-
- m->cBits= ""
- m->nN = m->nNum
- do while len( m->cBits) < m->nPlaces
- if m->nN > 0
- m->cBits = str( mod( m->nN, 2 ), 1 ) + m->cBits
- m->nN = int( m->nN / 2 )
- else
- m->cBits = "0" + m->cBits
- endif
- enddo
-
- RETURN m->cBits
- *-- Eof: Dec2Bin()
-
- FUNCTION Frac2Bin
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 03/01/1992
- *-- Notes.......: Converts the fractional part of an unsigned number
- *-- to a character string giving its ASCII binary
- *-- representation.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 03/01/1992 -- Original Release
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Frac2Bin(<nNum>,<nPlaces>)
- *-- Example.....: ? Frac2Bin( .35, 8 )
- *-- Returns.....: Character binary equivalent
- *-- Parameters..: nNum = number to convert
- *-- nPlaces = number of binary places number is to occupy
- *-----------------------------------------------------------------------
-
- parameters nNum, nPlaces
- private cBits, nN
-
- m->cBits = ""
- m->nN = m->nNum
- do while len( m->cBits ) < m->nPlaces
- if m->nN > 0
- m->nN = 2 * m->nN
- m->cBits = m->cBits + str( int( m->nN ), 1 )
- m->nN = m->nN - int( m->nN )
- else
- m->cBits = m->cBits + "0"
- endif
- enddo
-
- RETURN m->cBits
- *-- Eof: Frac2Bin()
-
- FUNCTION Num2Real
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/26/1992
- *-- Notes.......: Converts a number to the ASCII representation of
- *-- its storage in IEEE 4 or 8-byte real format, with
- *-- least significant byte (lowest in memory) first.
- *-- Provided for checking the values in .MEM files, or in
- *-- memory float-type variables if peeking.
- *-- Written for.: dBASE IV Version 1.5
- *-- ( may be adapted to earlier versions by requiring
- *-- fixed number of parameters.)
- *-- Rev. History: 03/01/92 - original function
- *-- 11/26/92 - revised to call Dec2Mkd(), etc., Jay
- *-- Parsons. The parameters of the revised version are
- *-- not the same as those of the original.
- *-- Calls.......: Dec2Mkd() Function in CONVERT.PRG
- *-- Dec2Mks() Function in CONVERT.PRG
- *-- Dec2Hex() Function in CONVERT.PRG
- *-- Called by...: Any
- *-- Usage.......: Num2Real(<nNum> [,<nBytes>] )
- *-- Example.....: ? Num2Real( 10E100, 8 )
- *-- Returns.....: Character string equivalent ( of a blank date, in
- *-- example )
- *-- Parameters..: nNum = number to convert
- *-- nBytes = number of bytes in conversion. Optional,
- *-- will be considered 8 ( long real ) unless
- *-- 4 is specified.
- *-----------------------------------------------------------------------
-
- parameters nNum, nBytes
- private cStr, nB, nX, MK
-
- m->nB = iif( type( "nBytes" ) = "N" .AND. m->nBytes = 4, 4, 8 )
- declare aMK[ m->nB ]
- m->cStr = ""
- if "" # iif( m->nB = 8, Dec2Mkd( m->nNum, "MK" ), ;
- Dec2Mks( m->nNum, "MK" ) )
- m->nX = 1
- do while m->nX <= m->nB
- m->cNext = Dec2Hex( asc( aMK[ m->nX ] ) )
- m->cStr = m->cStr + right( "0" + ;
- Dec2Hex( asc( aMK[ m->nX ] ) ), 2 ) + " "
- m->nX = m->nX + 1
- enddo
- endif
-
- RETURN trim( m->cStr )
- *-- Eof: Num2Real()
-
- FUNCTION Bin2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/25/1992
- *-- Notes.......: Converts a string containing a binary value
- *-- to its numeric (decimal) equivalent. Any characters
- *-- in the string other than "0" or "1" are ignored.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/25/1992 -- original function
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Bin2Dec( <cStr )
- *-- Example.....: ? Bin2Dec( "1000 0011" )
- *-- Returns.....: Numeric = equivalent ( 131 in example )
- *-- Parameters..: cStr1 = string holding binary value to convert
- *-----------------------------------------------------------------------
-
- parameters cStr
- private cLeft, cChar, nVal
-
- m->nVal = 0
- m->cLeft = m->cStr + "!"
- do while len( m->cLeft ) > 1
- m->cChar = left( m->cLeft, 1 )
- m->cLeft = substr( m->cLeft, 2 )
- if m->cChar $ "01"
- m->nVal = 2 * m->nVal + val( m->cChar )
- endif
- enddo
-
- RETURN m->nVal
- *-- Eof: Bin2Dec()
-
- FUNCTION Dec2Mkd
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/26/1992
- *-- Notes.......: Converts a numeric value to eight chr() values in
- *-- array. See notes to Dec2Mki() (CONVERT.PRG).
- *-- Returns null string if array not declared or declared
- *-- with too few elements.
- *-- This is roughly equivalent to MKD$() in BASIC.
- *-- Concatenation of the array elements gives the value
- *-- in IEEE long real format ( low-order byte first.)
- *-- From high to low, the 64 bits are:
- *-- 1 bit sign, 1 = negative
- *-- 11 bits exponent base 2 + 1023
- *-- 23 bits mantissa with initial "1." omitted as
- *-- understood.
- *-- dBASE uses this format for floats and dates internally
- *-- and in .MEM files; obviously, the dBASE float()
- *-- function will make the same conversion more quickly,
- *-- but creates difficulties in accessing the bytes as
- *-- converted.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/26/1992 -- original function
- *-- Calls.......: Bin2Dec() - Function in Convert.prg
- *-- Dec2Bin() - Function in Convert.prg
- *-- Frac2Bin() - Function in Convert.prg
- *-- Called by...: Any
- *-- Usage.......: Dec2Mkd( nVar, cName )
- *-- Example.....: ? Dec2Mkd( -1, "MK" )
- *-- Returns.....: name of array of which elements [ 1 ] - [ 8 ] contain
- *-- chr() values equivalent to bytes of value; or null
- *-- string.
- *-- Parameters..: nVar = number to convert
- *-- cName = name of array to use, which must be public and
- *-- previously declared with enough elements
- *-- Side effects: Alters contents of array
- *-----------------------------------------------------------------------
-
- parameters nVar, cName
- private cStr, cBin, nVal, nExp, nMant, nX
-
- m->cStr = ""
- if type( "&cName.[ 8 ]" ) # "U"
- m->cStr = m->cName
- if m->nVar = 0
- m->nX = 1
- do while m->nX < 9
- &cStr.[ m->nX ] = chr( 0 )
- m->nX = m->nX + 1
- enddo
- else
- m->cBin = iif( m->nVar < 0, "1", "0" )
- m->nVal = abs( m->nVar )
- m->nExp = int( log( m->nVar ) / log( 2 ) )
- m->nMant = m->nVal / 2 ^ m->nExp - 1
- m->cBin = m->cBin + Dec2Bin( m->nExp + 1023, 11 ) +;
- Frac2Bin( m->nMant, 52 )
- m->nX = 1
- do while m->nX < 9
- &cStr.[ m->nX ] = chr( Bin2Dec( substr( m->cBin, ;
- 65 - m->nX * 8, 8 ) ) )
- m->nX = m->nX + 1
- enddo
- endif
- endif
-
- RETURN m->cStr
- *-- EoF: Dec2Mkd()
-
- FUNCTION Dec2Mki
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/26/1992
- *-- Notes.......: Converts an integer in the range -32,768 to +32,767
- *-- to two chr() values equivalent to the two bytes
- *-- created by the BASIC MKI$ function.
- *-- Because of the impossibility of storing a null,
- *-- chr( 0 ), as a character in a dBASE string, the chr()
- *-- values are stored in the first two elements of an
- *-- array, with the low-order byte as element[ 1 ]. Array
- *-- name must be passed as second parameter. Array name
- *-- will be returned unless the parameter is out of range
- *-- or array has too few elements, in which case the null
- *-- string is returned.
- *-- Concatenation of the array elements such as by
- *-- fwrite( <nHandle>,<Arrayname>[ 1 ] )
- *-- fwrite( <nHandle>,<Arrayname>[ 2 ] )
- *-- writes the same value as the BASIC MKI$ function.
- *-- The same format is used by dBASE for internal storage
- *-- of integers within the range, and by C as a signed int
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/26/1992 -- original function
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Dec2Mki( nInt, cName )
- *-- Example.....: ? Dec2Mki( -1, "MK" )
- *-- Returns.....: name of array of which elements contain char
- *-- equivalents, chr( 255) and chr( 255 ) in example;
- *-- or null string.
- *-- Parameters..: nInt = integer to convert
- *-- cName = name of array to use, which must be public and
- *-- previously declared with enough elements
- *-- Side effects: Alters contents of array
- *-----------------------------------------------------------------------
-
- parameters nInt, cName
- private nVal, cStr, nX
-
- m->cStr = ""
- if type( "&cName.[ 2 ]" ) # "U"
- m->cStr = m->cName
- if m->nInt = int( m->nInt ) .and. m->nInt >= -32768;
- .and. m->nInt <= 32767
- m->nVal = m->nInt + iif( m->nInt < 0, 65536, 0 )
- m->nX = 1
- do while m->nX < 3
- &cStr.[ m->nX ] = chr( mod( m->nVal, 256 ) )
- m->nVal = int( m->nVal / 256 )
- m->nX = m->nX + 1
- enddo
- endif
- endif
-
- RETURN m->cStr
- *-- EoF: Dec2Mki()
-
- FUNCTION Dec2Mkl
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/26/1992
- *-- Notes.......: Converts an integer in the range -2^31 to +2^31 - 1
- *-- to four chr() values in array. See notes to Dec2Mki()
- *-- Returns null string if parameter is out of range or
- *-- array not declared or declared with too few elements.
- *-- This is mostly equivalent to MKL$() in BASIC.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/26/1992 -- original function
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Dec2Mkl( nInt, cName )
- *-- Example.....: ? Dec2Mkl( -1, "MK" )
- *-- Returns.....: name of array of which elements [ 1 ] - [ 4 ] contain
- *-- chr() values equivalent to bytes of value; or null
- *-- string.
- *-- Parameters..: nInt = integer to convert
- *-- cName = name of array to use, which must be public and
- *-- previously declared with enough elements
- *-- Side effects: Alters contents of array
- *-----------------------------------------------------------------------
-
- parameters nInt, cName
- private m->nVal, cStr, nX
-
- m->cStr = ""
- if type( "&cName.[ 4 ]" ) # "U"
- m->cStr = m->cName
- if m->nInt = int( m->nInt ) .and. m->nInt >= -2 ^ 31 .and.;
- m->nInt < 2 ^ 31
- m->nVal = m->nInt + iif( m->nInt < 0, 2 ^ 32, 0 )
- m->nX = 1
- do while m->nX < 5
- &cStr.[ m->nX ] = chr( mod( m->nVal, 256 ) )
- m->nVal = int( m->nVal / 256 )
- m->nX = m->nX + 1
- enddo
- endif
- endif
-
- RETURN m->cStr
- *-- EoF: Dec2Mkl()
-
- FUNCTION Dec2Mks
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/26/1992
- *-- Notes.......: Converts a numeric value to four chr() values in array
- *-- See notes to Dec2Mki().
- *-- Returns null string if array not declared or declared
- *-- with too few elements.
- *-- This is mostly equivalent to MKS$() in BASIC.
- *-- Concatenation of the array elements gives the value
- *-- in IEEE short real format ( low-order byte first.)
- *-- From high to low, the 32 bits are:
- *-- 1 bit sign, 1 = negative
- *-- 8 bits exponent base 2 + 127
- *-- 23 bits mantissa with initial "1." omitted as
- *-- understood.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/26/1992 -- original function
- *-- Calls.......: Bin2Dec() - Function in Convert.prg
- *-- Dec2Bin() - Function in Convert.prg
- *-- Frac2Bin() - Function in Convert.prg
- *-- Called by...: Any
- *-- Usage.......: Dec2Mks( nVar, cName )
- *-- Example.....: ? Dec2Mks( -1, "MK" )
- *-- Returns.....: name of array of which elements [ 1 ] - [ 4 ] contain
- *-- chr() values equivalent to bytes of value; or null
- *-- string.
- *-- Parameters..: nVar = number to convert
- *-- cName = name of array to use, which must be public and
- *-- previously declared with enough elements
- *-- Side effects: Alters contents of array
- *-----------------------------------------------------------------------
-
- parameters nVar, cName
- private cStr, cBin, nVal, nExp, nMant, nX
-
- m->cStr = ""
- if type( "&cName.[ 4 ]" ) # "U"
- m->cStr = m->cName
- if m->nVar = 0
- m->nX = 1
- do while m->nX < 5
- &cStr.[ m->nX ] = chr( 0 )
- m->nX = m->nX + 1
- enddo
- else
- m->cBin = iif( m->nVar < 0, "1", "0" )
- m->nVal = abs( m->nVar )
- m->nExp = int( log( m->nVar ) / log( 2 ) )
- m->nMant = m->nVal / 2 ^ m->nExp - 1
- m->cBin = m->cBin + Dec2Bin( m->nExp + 127, 8 ) + ;
- Frac2Bin( m->nMant, 23 )
- m->nX = 1
- do while m->nX < 5
- &cStr.[ m->nX ] = chr( Bin2Dec( substr( m->cBin, ;
- 33 - m->nX * 8, 8 ) ) )
- m->nX = m->nX + 1
- enddo
- endif
- endif
-
- RETURN m->cStr
- *-- EoF: Dec2Mks()
-
- FUNCTION Dec2MSks
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 12/01/1992
- *-- Notes.......: Converts a numeric value to four chr() values in
- *-- array. See notes to Dec2Mki(). USES OBSOLETE
- *-- MICROSOFT FORMAT. Returns null string if array not
- *-- declared or declared with too few elements.
- *-- This is mostly equivalent to MKS$() in old Microsoft
- *-- BASIC. Concatenation of the array elements gives the
- *-- value as stored in old MicroSoft four-byte real
- *-- format. From high to low, the 32 bits are:
- *-- 8 bits exponent base 2 + 128
- *-- 1 bit sign, 1 = negative
- *-- 23 bits mantissa with initial ".1" omitted as
- *-- understood.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 12/01/1992 -- original function
- *-- Calls.......: Bin2Dec() - Function in Convert.prg
- *-- Dec2Bin() - Function in Convert.prg
- *-- Frac2Bin() - Function in Convert.prg
- *-- Called by...: Any
- *-- Usage.......: Dec2MSks( nVar, cName )
- *-- Example.....: ? Dec2MSks( -1, "MK" )
- *-- Returns.....: name of array of which elements [ 1 ] - [ 4 ] contain
- *-- chr() values equivalent to bytes of value; or null
- *-- string.
- *-- Parameters..: nVar = number to convert
- *-- cName = name of array to use, which must be public and
- *-- previously declared with enough elements
- *-- Side effects: Alters contents of array
- *-----------------------------------------------------------------------
-
- parameters nVar, cName
- private cStr, cBin, nVal, nExp, nMant, nX
-
- m->cStr = ""
- if type( "&cName.[ 4 ]" ) # "U"
- m->cStr = m->cName
- if m->nVar = 0
- m->nX = 1
- do while m->nX < 5
- &cStr.[ m->nX ] = chr( 0 )
- m->nX = m->nX + 1
- enddo
- else
- m->cBin = iif( m->nVar < 0, "1", "0" )
- m->nVal = abs( m->nVar )
- m->nExp = int( log( m->nVar ) / log( 2 ) )
- m->nMant = m->nVal / 2 ^ m->nExp - 1
- m->cBin = Dec2Bin( m->nExp + 129, 8 ) + m->cBin + ;
- Frac2Bin( m->nMant, 23 )
- m->nX = 1
- do while m->nX < 5
- &cStr.[ m->nX ] = chr( Bin2Dec( substr( m->cBin,;
- 33 - m->nX * 8, 8 ) ) )
- m->nX = m->nX + 1
- enddo
- endif
- endif
-
- RETURN m->cStr
- *-- EoF: Dec2MSks()
-
- FUNCTION Mki2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/25/1992
- *-- Notes.......: Converts two bytes storing a signed short integer
- *-- ( as saved by the BASIC MKI$ function, e. g. )
- *-- to its numeric (decimal) equivalent. The format
- *-- accommodates values from 8000 ( -32,768 ) to
- *-- 7FFF ( +32,767 ); the low-order byte is stored first
- *-- and is expected as the first parameter.
- *-- This is the equivalent of CVI() in BASIC.
- *-- While this could easily be modified to accept
- *-- a two-character string as the parameter, dBASE and
- *-- particularly fread() will have trouble with such a
- *-- string that contains a null ( chr( 0 ) ).
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/25/1992 -- original function
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Mki2Dec( <c1>, <c2> )
- *-- Example.....: ? Mki2Dec( chr( 255 ), chr( 255 ) )
- *-- Returns.....: Numeric = equivalent ( -1 in example )
- *-- Parameters..: c1, c2 = chars holding value to convert
- *-----------------------------------------------------------------------
-
- parameters c1, c2
- private nVal
-
- m->nVal = asc( m->c1 ) + 256 * asc( m->c2 )
- if m->nVal > 32767
- m->nVal = m->nVal - 65536
- endif
-
- RETURN m->nVal
- *-- EoF: Mki2Dec()
-
- FUNCTION Mkl2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 11/26/1992
- *-- Notes.......: Converts four bytes storing a signed long integer
- *-- ( as saved by the BASIC MKL$ function, e. g. )
- *-- to its numeric (decimal) equivalent. The low-order
- *-- byte is stored first and is expected as the first
- *-- parameter.
- *-- This is the equivalent of CVL() in BASIC.
- *-- While this could easily be modified to accept
- *-- a four-character string as the parameter, dBASE and
- *-- particularly fread() will have trouble with such a
- *-- string that contains a null ( chr( 0 ) ).
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/26/1992 -- original function
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Mkl2Dec( <c1>, <c2>, <c3>, <c4> )
- *-- Example.....: ? Mkl2Dec( chr( 255 ), chr( 255 ), chr(255 ), ;
- *-- chr( 255) )
- *-- Returns.....: Numeric = equivalent ( -1 in example )
- *-- Parameters..: c1, c2, c3, c4 = chars holding value to convert
- *-----------------------------------------------------------------------
-
- parameters c1, c2, c3, c4
- private nVal, nX, cVar
-
- m->nVal = 0
- m->nX = 4
- do while m->nX > 0
- m->cVar = "c" + str( m->nX, 1 )
- m->nVal = 256 * m->nVal + asc( &cVar. )
- m->nX = m->nX - 1
- enddo
- if m->nVal >= 2 ^ 31
- m->nVal = m->nVal - 2 ^ 32
- endif
-
- RETURN m->nVal
- *-- EoF: Mkl2Dec()
-
- FUNCTION Num2Str
- *-----------------------------------------------------------------------
- *-- Programmer..: Angus Scott-Fleming (CIS: 75500,3223)
- *-- Date........: 06/09/1992
- *-- Notes.......: Converts a number to a string like str(), storing all
- *-- decimal places. Does not require knowing the number of
- *-- decimal places first.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 06/09/1992 -- Angus took Jay's routine and overhauled
- *-- it.
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Num2Str(<nNumber>)
- *-- Example.....: ? Num2Str( 415.25000000000001 )
- *-- Returns.....: Character = representation of number
- *-- ( "415.2500000000001" in example )
- *-- Parameters..: nNumber = number to represent
- *-----------------------------------------------------------------------
-
- parameters nNumber
- private nInteger, nFraction, cFracstr, nDec
-
- m->nInteger = int( m->nNumber )
- m->nFraction = abs( m->nNumber - m->nInteger )
- if m->nFraction = 0
- m->nFracStr = ""
- else
- *-- note that the maximum # of decimals is 18
- m->nFracStr = ltrim(str(m->nFraction,19,18))
- do while right(m->nFracStr,1) = "0"
- m->nFracStr = left(m->nFracStr,len(m->nFracStr)-1)
- enddo
- endif
-
- RETURN ltrim( str( m->nInteger ) ) + m->nFracStr
- *-- Eof: Num2Str()
-
- FUNCTION Mkd2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 04/12/1993
- *-- Notes.......: Converts eight bytes storing an IEEE long real value
- *-- ( as saved by the BASIC MKD$ function, e. g. )
- *-- to its numeric (decimal) equivalent. As usual, the
- *-- eight bytes of the value are stored low-order to high-
- *-- order, and are expected as parameters in that order.
- *-- From high to low, the 64 bits are:
- *-- 1 bit sign, 1 = negative
- *-- 11 bits exponent base 2 + 1023
- *-- 52 bits mantissa with initial "1." omitted as
- *-- understood.
- *-- The function is written to require eight separate
- *-- parameters rather than an eight-character string
- *-- because fread() will choke on reading the value as a
- *-- single string if it contains nulls ( chr( 0 ) ).
- *-- This is the equivalent of CVD() in BASIC.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/26/1992 -- original function
- *-- 04/12/1993 -- changed to work around dBASE IV
- *-- 2.0 mod() bug, Jay Parsons
- *-- Calls.......: Bin2Dec() - Function in Convert.prg
- *-- Called by...: Any
- *-- Usage.......: Mkd2Dec( <c1>, . . . <c8> )
- *-- Example.....: ? Mkd2Dec( chr( 0 ), chr( 0 ), chr( 0 ), chr( 0 ), ;
- *-- chr( 0 ), chr( 0 ), chr( 248 ), chr( 3 )
- *-- Returns.....: Numeric = equivalent ( 1 in example )
- *-- Parameters..: c1 . . . c8 = chars holding value to convert
- *-----------------------------------------------------------------------
-
- parameters c1, c2, c3, c4, c5, c6, c7, c8
- private nX, nY, cVar, cBin, nSign, nExp, cMant, nVal, nZ
-
- m->nX = 8
- m->nZ = 0
- m->cBin = ""
- do while m->nX > 0
- m->cVar = "c" + str( m->nX, 1 )
- m->nVal = asc( &cVar. )
- m->nZ = m->nZ + m->nVal
- m->nY = 7
- do while m->nY >=0
- m->cBin = m->cBin + iif( m->nVal >= 2 ^ m->nY, "1", "0" )
- m->nVal = iif( m->nVal = 0, 0, mod( m->nVal, 2 ^ m->nY ) )
- m->nY = m->nY - 1
- enddo
- m->nX = m->nX - 1
- enddo
- if m->nZ = 0
- m->nVal = 0
- else
- m->nSign = iif( left( m->cBin, 1 ) = "1", -1, 1 )
- m->nExp = Bin2Dec( substr( m->cBin, 2, 11) ) - 1023
- m->cMant = "1" + right( m->cBin, 52 )
- m->nVal = Bin2Dec( m->cMant ) * 2 ^ ( m->nExp - 52 ) * m->nSign
- endif
-
- RETURN m->nVal
- *-- EoF: Mkd2Dec()
-
- FUNCTION Mks2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 04/12/1993
- *-- Notes.......: Converts four bytes storing an IEEE short real value
- *-- ( as saved by the BASIC MKS$ function, e. g. )
- *-- to its numeric (decimal) equivalent. As usual, the
- *-- four bytes of the value are stored low-order to high-
- *-- order, and are expected as parameters in that order.
- *-- From high to low, the 32 bits are:
- *-- 1 bit sign, 1 = negative
- *-- 8 bits exponent base 2 + 127
- *-- 23 bits mantissa with initial "1." omitted as
- *-- understood.
- *-- The function is written to require four separate
- *-- parameters rather than a four-character string because
- *-- fread() will choke on reading the value as a single
- *-- string if it contains nulls ( chr( 0 ) ).
- *-- This is the equivalent of CVS() in BASIC.
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/25/1992 -- original function
- *-- 04/12/1993 -- changed to work around dBASE
- *-- IV 2.0 mod() bug, Jay Parsons
- *-- Calls.......: Bin2Dec() - Function in Convert.prg
- *-- Called by...: Any
- *-- Usage.......: Mks2Dec( <c1>, <c2>, <c3>, <c4> )
- *-- Example.....: ? Mks2Dec( chr( 0 ), chr( 0 ), chr( 128 ), chr( 63 ) )
- *-- Returns.....: Numeric = equivalent ( 1 in example )
- *-- Parameters..: c1, c2, c3, c4 = chars holding value to convert
- *-----------------------------------------------------------------------
-
- parameters c1, c2, c3, c4
- private nX, nY, cVar, cBin, nSign, nExp, cMant, nVal
-
- if asc( m->c1 ) + asc( m->c2 ) + asc( m->c3 ) + asc( m->c4 ) = 0
- m->nVal = 0
- else
- m->nX = 4
- m->cBin = ""
- do while m->nX > 0
- m->cVar = "c" + str( m->nX, 1 )
- m->nVal = asc( &cVar. )
- m->nY = 7
- do while m->nY >=0
- m->cBin = m->cBin + iif( m->nVal >= 2 ^ m->nY, "1", "0" )
- m->nVal = iif( m->nVal = 0, 0, mod( m->nVal, 2 ^ m->nY ) )
- m->nY = m->nY - 1
- enddo
- m->nX = m->nX - 1
- enddo
- m->nSign = iif( left( m->cBin, 1 ) = "1", -1, 1 )
- m->nExp = Bin2Dec( substr( m->cBin, 2, 8 ) ) - 127
- m->cMant = "1" + right( m->cBin, 23 )
- m->nVal = Bin2Dec( m->cMant ) * 2 ^ ( m->nExp - 23 ) * m->nSign
- endif
-
- RETURN m->nVal
- *-- EoF: Mks2Dec()
-
- FUNCTION MSks2Dec
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 04/12/1993
- *-- Notes.......: Converts four bytes storing an old-style Microsoft
- *-- short real value ( as saved by the BASIC MKS$
- *-- function, e. g. ) to its numeric (decimal) equivalent.
- *-- As usual, the four bytes of the value are stored low-
- *-- order to high-order, and are expected as parameters
- *-- in that order. From high to low, the 32 bits are:
- *-- 8 bits exponent base 2 + 128
- *-- 1 bit sign, 1 = negative
- *-- 23 bits mantissa with initial ".1" omitted as
- *-- understood.
- *-- The function is written to require four separate
- *-- parameters rather than a four-character string because
- *-- fread() will choke on reading the value as a single
- *-- string if it contains nulls ( chr( 0 ) ).
- *-- This is the equivalent of CVS() in old Microsoft BASIC
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/28/1992 -- original function
- *-- 04/12/1993 -- changed to work around dBASE IV
- *-- 2.0 mod() bug, Jay Parsons
- *-- Calls.......: Bin2Dec() - Function in Convert.prg
- *-- Called by...: Any
- *-- Usage.......: MSks2Dec( <c1>, <c2>, <c3>, <c4> )
- *-- Example.....: ? MSks2Dec( chr( 0 ), chr( 0 ), chr( 128 ), chr( 63 ))
- *-- Returns.....: Numeric = equivalent ( 1 in example )
- *-- Parameters..: c1, c2, c3, c4 = chars holding value to convert
- *-----------------------------------------------------------------------
-
- parameters c1, c2, c3, c4
- private nX, nY, cVar, cBin, nSign, nExp, cMant, nVal
-
- if asc( m->c1 ) + asc( m->c2 ) + asc( m->c3 ) + asc( m->c4 ) = 0
- m->nVal = 0
- else
- m->nX = 4
- m->cBin = ""
- do while m->nX > 0
- m->cVar = "c" + str( m->nX, 1 )
- m->nVal = asc( &cVar. )
- m->nY = 7
- do while m->nY >=0
- m->cBin = m->cBin + iif( m->nVal >= 2 ^ m->nY, "1", "0" )
- m->nVal = iif( m->nVal = 0, 0, mod( m->nVal, 2 ^ m->nY ) )
- m->nY = m->nY - 1
- enddo
- m->nX = m->nX - 1
- enddo
- m->nSign = iif( substr( m->cBin, 9, 1 ) = "1", -1, 1 )
- m->nExp = Bin2Dec( left( m->cBin, 8 ) ) - 128
- m->cMant = "1" + right( m->cBin, 23 )
- m->nVal = Bin2Dec( m->cMant ) * 2 ^ ( m->nExp - 24 ) * m->nSign
- endif
-
- RETURN m->nVal
- *-- EoF: MSks2Dec()
-
- FUNCTION Ordinal
- *-----------------------------------------------------------------------
- *-- Programmer..: Jay Parsons (CIS: 72662,1302)
- *-- Date........: 12/03/1992
- *-- Notes.......: Returns ordinal string for a positive integer < 100.
- *-- For higher numbers, use Num2Words on int( n/100 ),
- *-- then use this on mod( n, 100 ) or if mod( n, 100 ) =
- *-- 0, add "th" ).
- *-- Written for.: dBASE IV, 1.1
- *-- Rev. History: 11/19/1992 - original function
- *-- 12/03/1992 - Jay Parsons - changed notes and variable
- *-- names, replaced five lines with an "iif"
- *-- line
- *-- Calls.......: None
- *-- Called by...: Any
- *-- Usage.......: Ordinal( <nNum> )
- *-- Example.....: ? Ordinal( 31 ) && returns "thirty-first"
- *-- Returns.....: String giving ordinal value ( position ) of number,
- *-- or null
- *-- Parameters..: nNum = integer > 0 and < 100
- *-----------------------------------------------------------------------
-
- parameters nNum
- private cUnits, cTeens, cDecades, nRest, cOrd
-
- *-- 6 123456123456123456123456123456123456123456123456123456
- m->cUnits = " four fif six seven eigh nin ten "+;
- "eleventwelf "
- *-- 5 1234512345123451234512345123451234512345
- m->cTeens = " thir four fif six seveneigh nine "
- m->cDecades = " twen thir for fif six seveneigh nine"
-
- m->nRest = m->nNum
- m->cOrd = ""
- if m->nRest # int( nRet ) .OR. m->nRest < 1 .OR. m->nRest > 99
- m->nRest = 0
- endif
-
- if m->nRest > 19
- m->cOrd = trim( substr( m->cDecades, 5 * ;
- ( int( m->nRest / 10 ) - 1 ), 5 ) ) + "t"
- m->nRest = mod( m->nRest, 10 )
- m->cOrd = m->cOrd + iif( m->nRest = 0, "ieth", "y-" )
- endif
-
- do case
- case m->nRest > 12
- m->cOrd = m->cOrd + trim( substr( m->cTeens, 5 * ;
- ( m->nRest - 12 ), 5 ) ) + "teenth"
- case m->nRest > 3
- m->cOrd = m->cOrd + trim( substr( m->cUnits, ;
- 6 * ( m->nRest - 3 ), 6 ) ) + "th"
- case m->nRest > 0
- m->cOrd = m->cOrd + trim( substr( " first secondthird ", ;
- 6 * m->nRest, 6 ) )
- endcase
-
- RETURN m->cOrd
- *-- EoF() Ordinal
-
- *-----------------------------------------------------------------------
- *-- EoP: CONVERT.PRG
- *-----------------------------------------------------------------------